/*
 * @Descripttion:
 * @version:
 * @Author: ChenXiang
 * @Date: 2021-08-22 11:27:02
 * @LastEditors: ChenXiang
 * @LastEditTime: 2021-08-22 22:46:18
 */

import { TEXT } from "./const";

// 将虚拟都没转换未真实dom，插入container
function render(vnode, container) {
    const node = createNode(vnode);
    container.appendChild(node);
}

function createNode(vnode) {
    const { type, props } = vnode;
    let node = null;
    if (type === TEXT) {// 暂时只有文本和a标签
        node = document.createTextNode("")
    } else if (typeof type === 'string') {//原生节点
        node = document.createElement(type)
    } else if (typeof type === "function") {
        // 判断是函数组建还是类组件
        node =
            type.prototype.isReactComponent ?
                updateClassComponent(vnode) :
                updateFunctionComponent(vnode)
    } else {
        node = document.createDocumentFragment()
    }
    // 把 props.chidren 遍历 ，转成真实dom，再插入node
    reconcileChildren(props.children, node)
    updateNode(node, props)
    return node
}

function updateClassComponent(vnode) {
    const { type, props } = vnode;
    let cmp = new type(props)
    const vvnode = cmp.render();
    // 生成node节点
    const node = createNode(vvnode);
    return node
}

function updateFunctionComponent(vnode) {
    const { type, props } = vnode;
    const vvnode = type(props)
    const node = createNode(vvnode);
    return node
}

//更新属性值，如className,nodeValue
function updateNode(node, nextVal) {
    Object.keys(nextVal).filter(k => k !== 'children').forEach(k => {
        node[k] = nextVal[k]
    })
}

// 源码chidren可以是单个对象或数组，暂时统一成数组(在createElement)
function reconcileChildren(children, node) {
    for (let i = 0; i < children.length; i++) {
        let child = children[i];
        if (Array.isArray(child)) {// 支持数组
            for (let j = 0; j < child.length; j++) {
                render(child[j], node)
            }
        } else {
            render(child, node)
        }
    }
}

export default { render }